class Compute {
  plus(a, b) {
    return a + b
  }

  minus(a, b) {
    return a - b
  }

  mul(a, b) {
    return a * b
  }

  div(a, b) {
    return a / b
  }
}

class Calculator extends Compute {
  constructor(doc) {
    super() // 继承 Compute类

    // 先获取页面元素 getElementsByTagName
    const oCal = doc.getELementsByClassName('J_calculator')[0]

    this.fInput = oCal.getElementsByTagName('input')[0]
    this.sInput = oCal.getElementsByTagName('input')[1]

    this.oBtnGroup = oCal.getELementsByClassName('btn-group')[0]
    this.oBtnItems = this.oBtnGroup.getElementsByTagName('button')

    this.result = oCal.getELementsByClassName('result')[0]
    // 设置存储的数据对象 并期望值为
    // this.data = {
    //   // fNumber: xxx,
    //   // sNumber: xxx,
    //   // field: 'plus'
    // }
    this.data = this.defineData()
    this.btnIdx = 0 // btn点击切换

    console.log(this.data)
  }

  init() {
    this.bindEvent()

  }

  bindEvent() { // 绑定按钮、输入框对应的事件
    this.oBtnGroup.addEventListener('click', this.onFieldBtnClick.bind(this), false)
    this.fInput.addEventListener('input', this.onNumberInput.bind(this), false)
    this.sInput.addEventListener('input', this.onNumberInput.bind(this), false)

  }

  defineData() { // 监听各属性
    let _obj = {}, // 定义初始数据
        fNumber = 0,
        sNumber = 0,
        field = 'plus';
    const _self = this

    Object.defineProperties(_obj, {
      fNumber: {
        get() {
          console.log('"fNumber" is being got')
          return fNumber;
        },
        set(newVal) {
          fNumber = newVal;
          _self.computeResult(fNumber, sNumber, field)
          console.log(`The value "fNumber" has been changed.[${fNumber}]`)
        }
      },
      sNumber: {
        get() {
          console.log('"sNumber" is being got')
          return sNumber;
        },
        set(newVal) {
          sNumber = newVal;
          _self.computeResult(fNumber, sNumber, field) // 每次设置数据的时候计算一下结果
          console.log(`The value "sNumber" has been changed.[${sNumber}]`)
        }
      },
      field: {
        get() {
          console.log('"field" is being got')
          return field;
        },
        set(newVal) {
          field = newVal;
          _self.computeResult(fNumber, sNumber, field)
          console.log(`The value "field" has been changed.[${field}]`)
        }
      }


    })

    return _obj;
  }

  onFieldBtnClick(ev) {
    // 获取点击的元素 target
    const e = ev || window.event,
          tar = e.target || e.srcElement,
          tagName = tar.tagName.toLowerCase();
    // 判断是否点击的是button 是的话就更新
    tagName === 'button' && this.fieldUpdate(tar)
  }

  fieldUpdate(target) { // 更新按钮 样式、下标指向
    this.oBtnItems[this.btnIdx].className = ''
    this.btnIdx = [].indexOf.call(this.oBtnItems, target)
    target.className += 'current'
    // 切换按钮的时候也要同时改变按钮对应的值是哪种类型
    this.data.field = target.getAttribute('data-field')
  }

  onNumberInput(ev) { // 获取输入的值并区分
    const e = ev || window.event,
          tar = e.target || e.srcElement,
          className = tar.className, // 获取类名区分不同输入的值
          // 获取到的是字符串 需要清除空格 或 NAN
          val = Number(tar.value.replace(/\s+/g, '')) || 0;

    switch(className) {
      case 'f-input':
        this.data.fNumber = val
        break;
      case 's-input':
        this.data.sNumber = val
        break;
      default:
        break;
    }
  }

  computeResult(fNumber, sNumber, field) { // 计算结果
    // 通过父类的方法计算
    this.oResult.innerText = this[field](fNumber, sNumber)
  }
}

new Calculator(document).init()
